﻿using System;
using System.Data.Common;

using Dynamic.Core.Types;
using Microsoft.Practices.EnterpriseLibrary.Data.Instrumentation;

namespace Dynamic.Facades.EntLib.Data
{
    /// <summary>
    /// 数据库操作的基本实现类
    /// </summary>
    public class Database : Microsoft.Practices.EnterpriseLibrary.Data.Database
    {
        private DatabaseType _databaseType;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="db"></param>
        public Database(Microsoft.Practices.EnterpriseLibrary.Data.Database db)
            : this(db.ConnectionString, db.DbProviderFactory)
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="dbProviderFactory"></param>
        public Database(string connectionString, DbProviderFactory dbProviderFactory)
            : base(connectionString, dbProviderFactory)
        {
            _databaseType = GetDatabaseType(dbProviderFactory);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="dbProviderFactory"></param>
        /// <param name="databaseType"></param>
        public Database(string connectionString, DbProviderFactory dbProviderFactory, DatabaseType databaseType)
            : base(connectionString, dbProviderFactory)
        {
            _databaseType = databaseType;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="dbProviderFactory"></param>
        /// <param name="instrumentationProvider"></param>
        public Database(string connectionString, DbProviderFactory dbProviderFactory, Microsoft.Practices.EnterpriseLibrary.Data.Instrumentation.IDataInstrumentationProvider instrumentationProvider)
            : base(connectionString, dbProviderFactory, instrumentationProvider)
        {
            _databaseType = GetDatabaseType(dbProviderFactory);
        }

        /// <summary>
        /// 检索参数信息
        /// </summary>
        /// <param name="discoveryCommand"></param>
        protected override void DeriveParameters(DbCommand discoveryCommand)
        {
            //TODO:need to implement
            throw new NotImplementedException();
        }

        /// <summary>
        /// 通过连接类型判断数据库类型
        /// </summary>
        /// <param name="dbProviderFactory">连接类型</param>
        /// <returns>数据库类型</returns>
        private DatabaseType GetDatabaseType(DbProviderFactory dbProviderFactory)
        {
            if (dbProviderFactory is System.Data.SqlClient.SqlClientFactory)
            {
                return DatabaseType.SqlServer;
            }
            else if (dbProviderFactory is System.Data.OracleClient.OracleClientFactory)
            {
                return DatabaseType.Oracle;
            }

            //TODO:need to improve
            //else if (dbProviderFactory is System.Data.OleDb.OleDbFactory)
            //{
            //    return DatabaseType.OleDb;
            //}
            //else if (dbProviderFactory is System.Data.Odbc.OdbcFactory)
            //{
            //    return DatabaseType.Odbc;
            //}            

            return DatabaseType.SqlServer;
        }

        internal DbConnection GetNewOpenConnection()
        {
            DbConnection connection = null;
            try
            {
                try
                {
                    connection = CreateConnection();
                    connection.Open();
                }
                catch (Exception e)
                {
                    instrumentationProvider.FireConnectionFailedEvent(ConnectionStringNoCredentials, e);
                    throw;
                }

                instrumentationProvider.FireConnectionOpenedEvent();
            }
            catch
            {
                if (connection != null)
                    connection.Close();

                throw;
            }

            return connection;
        }

        /// <summary>
        /// 数据数据库类型
        /// </summary>
        public DatabaseType DatabaseType
        {
            get
            {
                return _databaseType;
            }
            set
            {
                _databaseType = value;
            }
        }
    }
}
